home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 551-575 / disk_562 / intuisup / editor / source.lzh / template.c < prev    next >
C/C++ Source or Header  |  1991-10-25  |  21KB  |  746 lines

  1.         /*************************************
  2.          *                                   *
  3.          *            Editor v1.0            *
  4.          *   by Torsten Jürgeleit in 07/91   *
  5.          *                                   *
  6.          *           Template part           *
  7.          *                                   *
  8.          *************************************/
  9.  
  10.     /* Includes */
  11.  
  12. #include "includes.h"
  13. #include "defines.h"
  14. #include "imports.h"
  15. #include "protos.h"
  16.  
  17.     /* Get current template by given ordinal number from list */
  18.  
  19.    struct Template *
  20. get_template_by_num(LONG num)
  21. {
  22.    struct Template  *tp;
  23.  
  24.    for (tp = get_head(&template_list.tl_List); tp;
  25.                           tp = get_succ(&tp->tp_Node)) {
  26.       if (!num--) {
  27.      CopyMem((BYTE *)&tp->tp_Box, (BYTE *)¤t_box, (LONG)
  28.                             sizeof(struct Box));
  29.      break;
  30.       }
  31.    }
  32.    selected_template = tp;
  33.    return(tp);
  34. }
  35.     /* Get current template by given mouse pos from list */
  36.  
  37.    struct Template *
  38. get_template_by_pos(SHORT x, SHORT y)
  39. {
  40.    struct Template  *tp;
  41.  
  42.    if (tp = find_template_by_pos(x, y)) {
  43.       CopyMem((BYTE *)&tp->tp_Box, (BYTE *)¤t_box, (LONG)
  44.                             sizeof(struct Box));
  45.    }
  46.    selected_template = tp;
  47.    return(tp);
  48. }
  49.     /* Find template by given mouse pos from list */
  50.  
  51.    struct Template *
  52. find_template_by_pos(SHORT x, SHORT y)
  53. {
  54.    struct Template  *tp;
  55.    struct Box       *box;
  56.  
  57.    /* First check info template */
  58.    if (info_displayed == TRUE) {
  59.       tp  = info_template;
  60.       box = &tp->tp_Box;
  61.       if (x >= box->bo_X1 && x <= box->bo_X2 && y >= box->bo_Y1 && y <=
  62.                                    box->bo_Y2) {
  63.      return(tp);
  64.       }
  65.    }
  66.  
  67.    /* Now check templates in list (from last to first) */
  68.    for (tp = get_tail(&template_list.tl_List); tp;
  69.                           tp = get_pred(&tp->tp_Node)) {
  70.       box = &tp->tp_Box;
  71.       if (x >= box->bo_X1 && x <= box->bo_X2 && y >= box->bo_Y1 && y <=
  72.                                    box->bo_Y2) {
  73.      return(tp);
  74.       }
  75.    }
  76.    return(NULL);
  77. }
  78.     /* Fix bounds of current template */
  79.  
  80.    VOID
  81. fix_template_bounds(VOID)
  82. {
  83.    struct Box  *box = ¤t_box;
  84.    SHORT temp;
  85.  
  86.    if (box->bo_X1 > box->bo_X2) {
  87.       temp       = box->bo_X2;
  88.       box->bo_X2 = box->bo_X1;
  89.       box->bo_X1 = temp;
  90.    }
  91.    if (box->bo_Y1 > box->bo_Y2) {
  92.       temp       = box->bo_Y2;
  93.       box->bo_Y2 = box->bo_Y1;
  94.       box->bo_Y1 = temp;
  95.    }
  96.    if (box->bo_X1 < 0) {
  97.       box->bo_X1 = 0;
  98.    }
  99.    if (box->bo_Y1 < 0) {
  100.       box->bo_Y1 = 0;
  101.    }
  102.    if (box->bo_X2 > pwin->Width) {
  103.       box->bo_X2 = pwin->Width;
  104.    }
  105.    if (box->bo_Y2 > pwin->Height) {
  106.       box->bo_Y2 = pwin->Height;
  107.    }
  108. }
  109.     /* Get modify mode from selected position */
  110.  
  111.    USHORT
  112. get_modify_mode(SHORT x, SHORT y)
  113. {
  114.    struct Template  *tp = selected_template;
  115.    struct Box       *box = &tp->tp_Box;
  116.    UBYTE  type = tp->tp_Type;
  117.    USHORT part_width  = (box->bo_X2 - box->bo_X1) / 8,
  118.       part_height = (box->bo_Y2 - box->bo_Y1) / 4,
  119.       modify_mode = MODIFY_MODE_MOVE;
  120.  
  121.    if (type != TEMPLATE_TYPE_TEXT && type != TEMPLATE_TYPE_CHECK &&
  122.                          type != TEMPLATE_TYPE_MX) {
  123.       if (x >= (box->bo_X2 - part_width) && x <= box->bo_X2 &&
  124.                y >= (box->bo_Y2 - part_height) && y <= box->bo_Y2) {
  125.      modify_mode = MODIFY_MODE_RESIZE;
  126.       }
  127.    }
  128.    return(modify_mode);
  129. }
  130.     /* Create new template and add it to template list */
  131.  
  132.    struct Template *
  133. create_template(VOID)
  134. {
  135.    struct TemplateList  *tl = &template_list;
  136.    struct Template      *tp;
  137.    SHORT status = EDITOR_STATUS_NORMAL;
  138.  
  139.    if (!(tp = AllocMem((LONG)sizeof(struct Template),
  140.                      (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
  141.       status = EDITOR_ERROR_OUT_OF_MEM;
  142.    } else {
  143.  
  144.       /* Init template */
  145.       tp->tp_Node.ln_Name = &tp->tp_TemplateName[0];
  146.       tp->tp_Type         = template_type;
  147.       CopyMem((BYTE *)¤t_box, (BYTE *)&tp->tp_Box, (LONG)
  148.                             sizeof(struct Box));
  149.       NewList(&tp->tp_TextList);
  150.       if ((status = init_default_template_data(tp, FALSE)) !=
  151.                              EDITOR_STATUS_NORMAL) {
  152.      free_template(tp);
  153.      tp = NULL;
  154.       } else {
  155.  
  156.      /* Add new template to list and increment counters */
  157.      AddTail(&tl->tl_List, &tp->tp_Node);
  158.      tl->tl_ListEntries++;
  159.      switch (TEMPLATE_GROUP(tp)) {
  160.         case TEMPLATE_GROUP_BORDER :
  161.            tp->tp_GroupEntryNum = ++tl->tl_BorderTemplates;
  162.            break;
  163.  
  164.         case TEMPLATE_GROUP_TEXT :
  165.            tp->tp_GroupEntryNum = ++tl->tl_TextTemplates;
  166.            break;
  167.  
  168.         case TEMPLATE_GROUP_GADGET :
  169.            tp->tp_GroupEntryNum = ++tl->tl_GadgetTemplates;
  170.            break;
  171.  
  172.      }
  173.      build_default_template_name(tp);
  174.      ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L,
  175.             USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_List);
  176.       }
  177.    }
  178.    show_error(status);
  179.    return(tp);
  180. }
  181.     /* Build default template name */
  182.  
  183.    VOID
  184. build_default_template_name(struct Template  *tp)
  185. {
  186.    BYTE   *buffer = &tp->tp_TemplateName[0];
  187.    USHORT num = tp->tp_GroupEntryNum;
  188.  
  189.    switch (TEMPLATE_GROUP(tp)) {
  190.       case TEMPLATE_GROUP_BORDER :
  191.      SPrintf(buffer, "BORDER%d", num);
  192.      break;
  193.  
  194.       case TEMPLATE_GROUP_TEXT :
  195.      SPrintf(buffer, "TEXT%d", num);
  196.      break;
  197.  
  198.       case TEMPLATE_GROUP_GADGET :
  199.      SPrintf(buffer, "GADGET%d", num);
  200.      break;
  201.    }
  202.    tp->tp_Flags = TEMPLATE_FLAG_DEFAULT_NAME;
  203. }
  204.     /* Init default template data */
  205.  
  206.    SHORT
  207. init_default_template_data(struct Template  *tp, BOOL default_name)
  208. {
  209.    struct TemplateList  *tl = &template_list;
  210.    struct BorderData    *bd;
  211.    struct TextData      *td;
  212.    struct GadgetData    *gd;
  213.    struct Box           *box = &tp->tp_Box;
  214.    UBYTE  group = TEMPLATE_GROUP(tp);
  215.    USHORT width = box->bo_X2 - box->bo_X1 + 1,
  216.       height = box->bo_Y2 - box->bo_Y1 + 1;
  217.    SHORT  status = EDITOR_STATUS_NORMAL;
  218.  
  219.    /* Init default template name */
  220.    if (default_name == TRUE) {
  221.       build_default_template_name(tp);
  222.    }
  223.  
  224.    /* Init default font */
  225.    CopyMem((BYTE *)&topaz80_attr, (BYTE *)&tp->tp_TextAttr, (LONG)
  226.                            sizeof(struct TextAttr));
  227.    if ((status = duplicate_string((BYTE **)&tp->tp_TextAttr.ta_Name,
  228.         (BYTE *)tp->tp_TextAttr.ta_Name)) == EDITOR_STATUS_NORMAL) {
  229.  
  230.       /* Init default template data */
  231.       switch (group) {
  232.      case TEMPLATE_GROUP_BORDER :
  233.         bd              = &tp->tp_Data.tp_BorderData;
  234.         bd->bd_Type     = BORDER_DATA_TYPE_BOX2_IN;
  235.         bd->bd_LeftEdge = box->bo_X1;
  236.         bd->bd_TopEdge  = box->bo_Y1;
  237.         bd->bd_Width    = width;
  238.         bd->bd_Height   = height;
  239.  
  240.         /* Mark end of border data */
  241.         (bd + 1)->bd_Type = INTUISUP_DATA_END;
  242.             break;
  243.  
  244.      case TEMPLATE_GROUP_TEXT :
  245.         td              = &tp->tp_Data.tp_TextData;
  246.         td->td_Type     = TEXT_DATA_TYPE_TEXT;
  247.         td->td_Flags    = 0;
  248.         td->td_LeftEdge = box->bo_X1;
  249.         td->td_TopEdge  = box->bo_Y1;
  250.         td->td_TextAttr = &tp->tp_TextAttr;
  251.         if ((status = duplicate_string(&td->td_Text, "Text")) ==
  252.                              EDITOR_STATUS_NORMAL) {
  253.            /* Calc size of text for template box */
  254.            box        = &tp->tp_Box;
  255.            box->bo_X2 = box->bo_X1 + IPrintText(pri, pwin, td->td_Text,
  256.                    td->td_LeftEdge, td->td_TopEdge, td->td_Type,
  257.                   TEXT_DATA_FLAG_NO_PRINT, td->td_TextAttr) - 1;
  258.            box->bo_Y2 = box->bo_Y1 + td->td_TextAttr->ta_YSize - 1;
  259.         }
  260.  
  261.         /* Mark end of text data */
  262.         (td + 1)->td_Type = INTUISUP_DATA_END;
  263.         break;
  264.  
  265.      case TEMPLATE_GROUP_GADGET :
  266.         gd              = &tp->tp_Data.tp_GadgetData;
  267.         gd->gd_Type     = tp->tp_Type - FIRST_GADGET_TEMPLATE_TYPE + 1;
  268.         gd->gd_Flags    = 0;
  269.         gd->gd_LeftEdge = box->bo_X1;
  270.         gd->gd_TopEdge  = box->bo_Y1;
  271.         gd->gd_Width    = width;
  272.         gd->gd_Height   = height;
  273.         gd->gd_Text     = NULL;
  274.         gd->gd_TextAttr = &tp->tp_TextAttr;
  275.         switch (gd->gd_Type) {
  276.            case GADGET_DATA_TYPE_BUTTON :
  277.           status = duplicate_string(&gd->gd_Text, "Button");
  278.           break;
  279.  
  280.            case GADGET_DATA_TYPE_CHECK :
  281.           gd->gd_SpecialData.gd_CheckData.gd_CheckSelected = 1;
  282.           break;
  283.  
  284.            case GADGET_DATA_TYPE_MX :
  285.           gd->gd_Flags                                 |= GADGET_DATA_FLAG_TEXT_LEFT;
  286.           gd->gd_SpecialData.gd_MXData.gd_MXSpacing     = 1;
  287.           gd->gd_SpecialData.gd_MXData.gd_MXActiveEntry = 0;
  288.           if ((status = build_template_text_list(tp,
  289.                           &default_mx_text_array[0])) ==
  290.                              EDITOR_STATUS_NORMAL) {
  291.              status = build_template_text_array(tp);
  292.           }
  293.           break;
  294.  
  295.            case GADGET_DATA_TYPE_STRING :
  296.           gd->gd_SpecialData.gd_InputData.gd_InputLen          = 10;
  297.           gd->gd_SpecialData.gd_InputData.gd_InputActivateNext = 0;
  298.           gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev = 0;
  299.           status = duplicate_string(&gd->gd_SpecialData.gd_InputData.gd_InputDefault, "String");
  300.           break;
  301.  
  302.            case GADGET_DATA_TYPE_INTEGER :
  303.           gd->gd_SpecialData.gd_InputData.gd_InputLen          = 10;
  304.           gd->gd_SpecialData.gd_InputData.gd_InputActivateNext = 0;
  305.           gd->gd_SpecialData.gd_InputData.gd_InputActivatePrev = 0;
  306.           gd->gd_SpecialData.gd_InputData.gd_InputDefault      = (BYTE *)123;
  307.           break;
  308.  
  309.            case GADGET_DATA_TYPE_SLIDER :
  310.           if (width / 2 < height) {
  311.              gd->gd_Flags = GADGET_DATA_FLAG_ORIENTATION_VERT;
  312.           }
  313.           gd->gd_SpecialData.gd_SliderData.gd_SliderMin   = 0;
  314.           gd->gd_SpecialData.gd_SliderData.gd_SliderMax   = 10;
  315.           gd->gd_SpecialData.gd_SliderData.gd_SliderLevel = 5;
  316.           break;
  317.  
  318.            case GADGET_DATA_TYPE_SCROLLER :
  319.           if (width / 2 < height) {
  320.              gd->gd_Flags = GADGET_DATA_FLAG_ORIENTATION_VERT;
  321.           }
  322.           gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerVisible = 2;
  323.           gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTotal   = 10;
  324.           gd->gd_SpecialData.gd_ScrollerData.gd_ScrollerTop     = 5;
  325.           break;
  326.  
  327.            case GADGET_DATA_TYPE_CYCLE :
  328.           gd->gd_SpecialData.gd_CycleData.gd_CycleActive = 0;
  329.           if ((status = build_template_text_list(tp,
  330.                        &default_cycle_text_array[0])) ==
  331.                              EDITOR_STATUS_NORMAL) {
  332.              status = build_template_text_array(tp);
  333.           }
  334.           break;
  335.  
  336.            case GADGET_DATA_TYPE_COUNT :
  337.           gd->gd_SpecialData.gd_CountData.gd_CountMin   = 10;
  338.           gd->gd_SpecialData.gd_CountData.gd_CountMax   = 50;
  339.           gd->gd_SpecialData.gd_CountData.gd_CountValue = 30;
  340.           break;
  341.  
  342.            case GADGET_DATA_TYPE_LISTVIEW :
  343.           gd->gd_Flags                                         |= GADGET_DATA_FLAG_TEXT_ABOVE;
  344.           gd->gd_SpecialData.gd_ListViewData.gd_ListViewSpacing = 0;
  345.           gd->gd_SpecialData.gd_ListViewData.gd_ListViewTop     = 0;
  346.           gd->gd_SpecialData.gd_ListViewData.gd_ListViewList    = &tp->tp_TextList;
  347.           status = build_template_text_list(tp,
  348.                        &default_listview_text_array[0]);
  349.           break;
  350.  
  351.            case GADGET_DATA_TYPE_PALETTE :
  352.           if (width / 2 < height) {
  353.              gd->gd_Flags |= GADGET_DATA_FLAG_PALETTE_INDICATOR_TOP;
  354.           }
  355.           gd->gd_Flags                                           |= GADGET_DATA_FLAG_TEXT_ABOVE;
  356.           gd->gd_SpecialData.gd_PaletteData.gd_PaletteDepth       = 2;
  357.           gd->gd_SpecialData.gd_PaletteData.gd_PaletteColorOffset = 0;
  358.           gd->gd_SpecialData.gd_PaletteData.gd_PaletteActiveColor = 2;
  359.           break;
  360.         }
  361.  
  362.         /* Mark end of gadget data */
  363.         (gd + 1)->gd_Type = INTUISUP_DATA_END;
  364.         break;
  365.       }
  366.    }
  367.    return(status);
  368. }
  369.     /* Clone template and optional add it to template list */
  370.  
  371.    struct Template *
  372. clone_template(struct Template  *old_tp, BOOL full_clone)
  373. {
  374.    struct TemplateList  *tl = &template_list;
  375.    struct Template      *new_tp;
  376.    SHORT status = EDITOR_STATUS_NORMAL;
  377.  
  378.    if (!(new_tp = AllocMem((LONG)sizeof(struct Template),
  379.                      (LONG)MEMF_PUBLIC | MEMF_CLEAR))) {
  380.       status = EDITOR_ERROR_OUT_OF_MEM;
  381.    } else {
  382.  
  383.       /* Init template */
  384.       CopyMem((BYTE *)old_tp, (BYTE *)new_tp, (LONG)sizeof(struct Template));
  385.       new_tp->tp_Node.ln_Name = &new_tp->tp_TemplateName[0];
  386.       NewList(&new_tp->tp_TextList);
  387.       if (full_clone == FALSE) {
  388.      CopyMem((BYTE *)¤t_box, (BYTE *)&new_tp->tp_Box, (LONG)
  389.                             sizeof(struct Box));
  390.       }
  391.       if ((status = clone_template_data(old_tp, new_tp)) !=
  392.                              EDITOR_STATUS_NORMAL) {
  393.      free_template(new_tp);
  394.      new_tp = NULL;
  395.       } else {
  396.      if (full_clone == FALSE) {
  397.  
  398.         /* Add new template to list and increment counters */
  399.         AddTail(&tl->tl_List, &new_tp->tp_Node);
  400.         tl->tl_ListEntries++;
  401.         switch (TEMPLATE_GROUP(new_tp)) {
  402.            case TEMPLATE_GROUP_BORDER :
  403.           new_tp->tp_GroupEntryNum = ++tl->tl_BorderTemplates;
  404.           break;
  405.  
  406.            case TEMPLATE_GROUP_TEXT :
  407.           new_tp->tp_GroupEntryNum = ++tl->tl_TextTemplates;
  408.           break;
  409.  
  410.            case TEMPLATE_GROUP_GADGET :
  411.           new_tp->tp_GroupEntryNum = ++tl->tl_GadgetTemplates;
  412.           break;
  413.         }
  414.         build_default_template_name(new_tp);
  415.         ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L,
  416.             USE_CURRENT_VALUE, USE_CURRENT_VALUE, &tl->tl_List);
  417.      }
  418.       }
  419.    }
  420.    show_error(status);
  421.    return(new_tp);
  422. }
  423.     /* Clone template data */
  424.  
  425.    STATIC SHORT
  426. clone_template_data(struct Template  *old_tp, struct Template  *new_tp)
  427. {
  428.    struct BorderData  *new_bd;
  429.    struct TextData    *old_td, *new_td;
  430.    struct GadgetData  *old_gd, *new_gd;
  431.    struct Box         *box = &new_tp->tp_Box;
  432.    SHORT status = EDITOR_STATUS_NORMAL;
  433.  
  434.    /* Clear data pointers */
  435.    new_tp->tp_TextAttr.ta_Name = NULL;
  436.    switch (TEMPLATE_GROUP(new_tp)) {
  437.       case TEMPLATE_GROUP_BORDER :
  438.      new_bd = &new_tp->tp_Data.tp_BorderData;
  439.          break;
  440.  
  441.       case TEMPLATE_GROUP_TEXT :
  442.      old_td = &old_tp->tp_Data.tp_TextData;
  443.      new_td = &new_tp->tp_Data.tp_TextData;
  444.      if (new_td->td_Type == TEXT_DATA_TYPE_TEXT) {
  445.         new_td->td_Text = NULL;
  446.      }
  447.      break;
  448.  
  449.       case TEMPLATE_GROUP_GADGET :
  450.      old_gd          = &old_tp->tp_Data.tp_GadgetData;
  451.      new_gd          = &new_tp->tp_Data.tp_GadgetData;
  452.      new_gd->gd_Text = NULL;
  453.      switch (new_gd->gd_Type) {
  454.         case GADGET_DATA_TYPE_BUTTON :
  455.         case GADGET_DATA_TYPE_CHECK :
  456.         case GADGET_DATA_TYPE_INTEGER :
  457.         case GADGET_DATA_TYPE_SLIDER :
  458.         case GADGET_DATA_TYPE_SCROLLER :
  459.         case GADGET_DATA_TYPE_COUNT :
  460.         case GADGET_DATA_TYPE_PALETTE :
  461.            break;
  462.  
  463.         case GADGET_DATA_TYPE_MX :
  464.            new_gd->gd_SpecialData.gd_MXData.gd_MXTextArray = NULL;
  465.            break;
  466.  
  467.         case GADGET_DATA_TYPE_CYCLE :
  468.            new_gd->gd_SpecialData.gd_CycleData.gd_CycleTextArray = NULL;
  469.            break;
  470.  
  471.         case GADGET_DATA_TYPE_STRING :
  472.            new_gd->gd_SpecialData.gd_InputData.gd_InputDefault = NULL;
  473.            break;
  474.  
  475.         case GADGET_DATA_TYPE_LISTVIEW :
  476.            new_gd->gd_SpecialData.gd_ListViewData.gd_ListViewList = &new_tp->tp_TextList;
  477.            break;
  478.      }
  479.      break;
  480.    }
  481.  
  482.    /* Allocate new data */
  483.    if ((status = duplicate_string((BYTE **)&new_tp->tp_TextAttr.ta_Name,
  484.         (BYTE *)old_tp->tp_TextAttr.ta_Name)) == EDITOR_STATUS_NORMAL) {
  485.       switch (TEMPLATE_GROUP(new_tp)) {
  486.      case TEMPLATE_GROUP_BORDER :
  487.         new_bd->bd_LeftEdge = box->bo_X1;
  488.         new_bd->bd_TopEdge  = box->bo_Y1;
  489.         break;
  490.  
  491.      case TEMPLATE_GROUP_TEXT :
  492.         new_td->td_LeftEdge = box->bo_X1;
  493.         new_td->td_TopEdge  = box->bo_Y1;
  494.         new_td->td_TextAttr = &new_tp->tp_TextAttr;
  495.         if (new_td->td_Type == TEXT_DATA_TYPE_TEXT) {
  496.            status = duplicate_string(&new_td->td_Text, old_td->td_Text);
  497.         }
  498.         break;
  499.  
  500.      case TEMPLATE_GROUP_GADGET :
  501.         new_gd->gd_LeftEdge = box->bo_X1;
  502.         new_gd->gd_TopEdge  = box->bo_Y1;
  503.         new_gd->gd_TextAttr = &new_tp->tp_TextAttr;
  504.         if ((status = duplicate_string(&new_gd->gd_Text,
  505.                 old_gd->gd_Text)) == EDITOR_STATUS_NORMAL) {
  506.            switch (new_gd->gd_Type) {
  507.           case GADGET_DATA_TYPE_BUTTON :
  508.           case GADGET_DATA_TYPE_CHECK :
  509.           case GADGET_DATA_TYPE_INTEGER :
  510.           case GADGET_DATA_TYPE_SLIDER :
  511.           case GADGET_DATA_TYPE_SCROLLER :
  512.           case GADGET_DATA_TYPE_COUNT :
  513.           case GADGET_DATA_TYPE_PALETTE :
  514.              break;
  515.  
  516.           case GADGET_DATA_TYPE_MX :
  517.           case GADGET_DATA_TYPE_CYCLE :
  518.              if ((status = duplicate_text_list(old_tp, new_tp)) ==
  519.                              EDITOR_STATUS_NORMAL) {
  520.             status = build_template_text_array(new_tp);
  521.              }
  522.              break;
  523.  
  524.           case GADGET_DATA_TYPE_STRING :
  525.              status = duplicate_string(&new_gd->gd_SpecialData.gd_InputData.gd_InputDefault, old_gd->gd_SpecialData.gd_InputData.gd_InputDefault);
  526.              break;
  527.  
  528.           case GADGET_DATA_TYPE_LISTVIEW :
  529.              status = duplicate_text_list(old_tp, new_tp);
  530.              break;
  531.            }
  532.         }
  533.         break;
  534.       }
  535.    }
  536.    return(status);
  537. }
  538.     /* Display template */
  539.  
  540.    VOID
  541. display_template(struct Template  *tp)
  542. {
  543.    struct GadgetData  *gd;
  544.    struct TextFont    *tf;
  545.    APTR   gl;
  546.    USHORT *dim;
  547.  
  548.    switch (TEMPLATE_GROUP(tp)) {
  549.       case TEMPLATE_GROUP_BORDER :
  550.      IDisplayBorders(pri, pwin, &tp->tp_Data.tp_BorderData, 0, 0);
  551.      break;
  552.  
  553.       case TEMPLATE_GROUP_TEXT :
  554.      tf = open_font(&tp->tp_TextAttr);
  555.      IDisplayTexts(pri, pwin, &tp->tp_Data.tp_TextData, 0, 0);
  556.      close_font(tf);
  557.      break;
  558.  
  559.       case TEMPLATE_GROUP_GADGET :
  560.      gd = &tp->tp_Data.tp_GadgetData;
  561.      if (!(gl = ICreateGadgets(pri, gd, 0, 0))) {
  562.         show_error(EDITOR_ERROR_OUT_OF_MEM);
  563.      } else {
  564.         IDisplayGadgets(pwin, gl);
  565.  
  566.         /* Update template box with gadget size */
  567.         dim = (USHORT *)(IGadgetAddress(gl, 0) + 1);
  568.         switch (gd->gd_Type) {
  569.            case GADGET_DATA_TYPE_CHECK :
  570.            case GADGET_DATA_TYPE_MX :
  571.            case GADGET_DATA_TYPE_PALETTE :
  572.            case GADGET_DATA_TYPE_LISTVIEW :
  573.           tp->tp_Box.bo_X2 = tp->tp_Box.bo_X1 + dim[0] - 1;
  574.           tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] - 1;
  575.           break;
  576.  
  577.            case GADGET_DATA_TYPE_STRING :
  578.            case GADGET_DATA_TYPE_INTEGER :
  579.           tp->tp_Box.bo_X2 = tp->tp_Box.bo_X1 + dim[0] - 1;
  580.           if (gd->gd_Flags & GADGET_DATA_FLAG_NO_BORDER) {
  581.              tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] - 1;
  582.           } else {
  583.              tp->tp_Box.bo_Y2 = tp->tp_Box.bo_Y1 + dim[1] + 5;
  584.           }
  585.           break;
  586.         }
  587.         IRemoveGadgets(gl);
  588.         IFreeGadgets(gl);
  589.      }
  590.      break;
  591.    }
  592. }
  593.     /* Refresh all templates */
  594.  
  595.    VOID
  596. refresh_all_templates(VOID)
  597. {
  598.    struct TemplateList  *tl = &template_list;
  599.    struct Template      *tp;
  600.  
  601.    clear_project_window(tl->tl_Flags);
  602.    print_project_window_title();
  603.    if (editor_mode == EDITOR_MODE_USE) {
  604.       IRefreshGadgets(use_gl);
  605.  
  606.       /* Refresh non gadget templates */
  607.       for (tp = get_head(&tl->tl_List); tp; tp = get_succ(&tp->tp_Node)) {
  608.      if (TEMPLATE_GROUP(tp) != TEMPLATE_GROUP_GADGET) {
  609.         display_template(tp);
  610.      }
  611.       }
  612.    } else {
  613.       for (tp = get_head(&tl->tl_List); tp; tp = get_succ(&tp->tp_Node)) {
  614.      display_template(tp);
  615.       }
  616.    }
  617. }
  618.     /* Free template list */
  619.  
  620.    VOID
  621. free_template_list(VOID)
  622. {
  623.    struct TemplateList  *tl = &template_list;
  624.    struct Template      *tp;
  625.    struct List          *list = &tl->tl_List;
  626.  
  627.    while (tp = (struct Template *)RemHead(list)) {
  628.       switch (TEMPLATE_GROUP(tp)) {
  629.      case TEMPLATE_GROUP_BORDER :
  630.         tl->tl_BorderTemplates--;
  631.         break;
  632.  
  633.      case TEMPLATE_GROUP_TEXT :
  634.         tl->tl_TextTemplates--;
  635.         break;
  636.  
  637.      case TEMPLATE_GROUP_GADGET :
  638.         tl->tl_GadgetTemplates--;
  639.         break;
  640.       }
  641.       tl->tl_ListEntries--;
  642.       free_template(tp);
  643.    }
  644.    tl->tl_Flags &= ~TEMPLATE_LIST_FLAG_CHANGED;
  645.    MWCheck();
  646. }
  647.     /* Free template */
  648.  
  649.    VOID
  650. free_template(struct Template  *tp)
  651. {
  652.    free_template_data(tp);
  653.    FreeMem(tp, (LONG)sizeof(struct Template));
  654. }
  655.     /* Free template data */
  656.  
  657.    VOID
  658. free_template_data(struct Template  *tp)
  659. {
  660.    struct TextData    *td;
  661.    struct GadgetData  *gd;
  662.  
  663.    DosFreeMem(tp->tp_TextAttr.ta_Name);
  664.    switch (TEMPLATE_GROUP(tp)) {
  665.       case TEMPLATE_GROUP_BORDER :
  666.      break;
  667.  
  668.       case TEMPLATE_GROUP_TEXT :
  669.      td = &tp->tp_Data.tp_TextData;
  670.      if (td->td_Type == TEXT_DATA_TYPE_TEXT) {
  671.         DosFreeMem(td->td_Text);
  672.      }
  673.      td->td_Text = NULL;
  674.      break;
  675.  
  676.       case TEMPLATE_GROUP_GADGET :
  677.      gd = &tp->tp_Data.tp_GadgetData;
  678.      DosFreeMem(gd->gd_Text);
  679.      gd->gd_Text = NULL;
  680.      switch (gd->gd_Type) {
  681.         case GADGET_DATA_TYPE_BUTTON :
  682.         case GADGET_DATA_TYPE_CHECK :
  683.         case GADGET_DATA_TYPE_INTEGER :
  684.         case GADGET_DATA_TYPE_SLIDER :
  685.         case GADGET_DATA_TYPE_SCROLLER :
  686.         case GADGET_DATA_TYPE_COUNT :
  687.         case GADGET_DATA_TYPE_PALETTE :
  688.            break;
  689.  
  690.         case GADGET_DATA_TYPE_MX :
  691.         case GADGET_DATA_TYPE_CYCLE :
  692.            free_template_text_array(tp);
  693.         case GADGET_DATA_TYPE_LISTVIEW :
  694.            free_template_text_list(tp);
  695.            break;
  696.  
  697.         case GADGET_DATA_TYPE_STRING :
  698.            DosFreeMem(gd->gd_SpecialData.gd_InputData.gd_InputDefault);
  699.            break;
  700.      }
  701.      break;
  702.    }
  703. }
  704.     /* Delete template */
  705.  
  706.    VOID
  707. delete_template(struct Template  *tp)
  708. {
  709.    struct TemplateList  *tl = &template_list;
  710.    struct Template      *succ_tp;
  711.    UBYTE group = TEMPLATE_GROUP(tp);
  712.  
  713.    /* Remove template from list, decrement counters and free template */
  714.    succ_tp = get_succ(&tp->tp_Node);
  715.    Remove(&tp->tp_Node);
  716.    tl->tl_ListEntries--;
  717.    switch (group) {
  718.       case TEMPLATE_GROUP_BORDER :
  719.      tl->tl_BorderTemplates--;
  720.      break;
  721.  
  722.       case TEMPLATE_GROUP_TEXT :
  723.      tl->tl_TextTemplates--;
  724.      break;
  725.  
  726.       case TEMPLATE_GROUP_GADGET :
  727.      tl->tl_GadgetTemplates--;
  728.      break;
  729.    }
  730.    free_template(tp);
  731.  
  732.    /* Update default template names and refresh template list */
  733.    for (tp = succ_tp; tp; tp = get_succ(&tp->tp_Node)) {
  734.       if (TEMPLATE_GROUP(tp) == group) {
  735.      tp->tp_GroupEntryNum--;
  736.      if (tp->tp_Flags & TEMPLATE_FLAG_DEFAULT_NAME) {
  737.         build_default_template_name(tp);
  738.      }
  739.       }
  740.    }
  741.    ISetGadgetAttributes(egl, EDITOR_GADGET_TEMPLATES, 0L, USE_CURRENT_VALUE,
  742.                        USE_CURRENT_VALUE, &tl->tl_List);
  743.    refresh_all_templates();
  744.    tl->tl_Flags |= TEMPLATE_LIST_FLAG_CHANGED;
  745. }
  746.